/*
Copyright SecureKey Technologies Inc. All Rights Reserved.

SPDX-License-Identifier: Apache-2.0
*/

package resource

import (
	pb "git.cloud.inspur.com/ichain/ichain-protos-go/inode"
	"git.cloud.inspur.com/ichain/ichain-sdk-go/pkg/providers/ichain"
	"git.cloud.inspur.com/ichain/ichain-sdk-go/thirdparty/ichain/protoutil"
	"github.com/pkg/errors"
)

const (
	lscc                   = "SC_LIFECYCLE"
	lsccInstall            = "install"
	lsccInstalledContracts = "getinstalledcontracts"
)

type ContractInstallRequest struct {
	Name    string
	Path    string
	Version string
	Package *ContractPackage
}

type ContractPackage struct {
	Type pb.ContractSpec_Type
	Code []byte
}

func CreateContractInstallProposal(tx ichain.Transactor, request ContractInstallRequest) (*ichain.TransactionProposal, error) {
	cir, err := createInstallInvokeRequest(request)
	if err != nil {
		return nil, errors.WithMessage(err, "creating lscc install invocation request failed")
	}

	return tx.CreateTxProposal(cir)
}

func createInstallInvokeRequest(request ContractInstallRequest) (ichain.ContractInvokeRequest, error) {
	args := [][]byte{}

	ccds := &pb.ContractDeploymentSpec{ContractSpec: &pb.ContractSpec{
		Type: request.Package.Type, ContractId: &pb.ContractID{Name: request.Name, Path: request.Path, Version: request.Version}},
		CodePackage: request.Package.Code}

	ccdsBytes, err := protoutil.Marshal(ccds)
	if err != nil {
		return ichain.ContractInvokeRequest{}, errors.WithMessage(err, "marshal of contract deployment spec failed")
	}
	args = append(args, ccdsBytes)

	cir := ichain.ContractInvokeRequest{
		ContractID: lscc,
		Fcn:        lsccInstall,
		Args:       args,
	}
	return cir, nil
}

func createInstalledContractsInvokeRequest() ichain.ContractInvokeRequest {
	cir := ichain.ContractInvokeRequest{
		ContractID: lscc,
		Fcn:        lsccInstalledContracts,
	}
	return cir
}
